﻿// -------------------------------------------------------------------------
//    @FileName         :    NFBagPageOpMgrInterface.cpp
//    @Author           :    Gao.Yi
//    @Date             :    2025-10-21
//    @Email			:    445267987@qq.com
//    @Module           :    NFBagPageOpMgrInterface
//    @Desc             :    背包页签操作管理抽象类的实现：路由添加/删除、提交、生效。
//                           统一处理货币直通、页签选择、过期/绑定过滤、错误码聚合。
// -------------------------------------------------------------------------

#include "NFBagPageOpMgrInterface.h"
#include <NFBagPageInterfacePackage.h>
#include <NFBagPageOp.h>
#include "proto_event.nanopb.h"
#include "proto_event.pb.h"
#include "NFBagDefine.h"
#include "proto_cs_cmd.nanopb.h"

/**
 * @brief 构造函数
 * @param ownerId 所有者ID
 * @param iOpReason 操作原因
 * @param bNeedCommit 是否需要提交
 */
NFBagPageOpMgrInterface::NFBagPageOpMgrInterface(uint64_t ownerId, int iOpReason, bool bNeedCommit) : NFBagBaseOp(ownerId, bNeedCommit), m_enPackageOpReason(iOpReason)
{
    m_enBindStatForAdd = EN_BT_AUTO;
    m_bFromMail = false;
    m_dwDelExpireUnixSec = 0;
    m_bForbidAddWheFull = false;
}

/**
 * @brief 析构函数
 */
NFBagPageOpMgrInterface::~NFBagPageOpMgrInterface()
{
}

/**
 * @brief 自动选择合适页签添加物品
 * 根据物品与操作原因计算目标页签，然后调用 AddToBagPage 完成添加
 */
int NFBagPageOpMgrInterface::AddToBag(WillAddItemData& stWillAddItemData, int iNum, int* pAddedNum)
{
    int iRetCode = 0;

    // 根据物品与操作原因计算合适的页签类型
    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(stWillAddItemData, m_enPackageOpReason, iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "CServicePackage::CalcAddBagTab");

    // 添加到指定页签
    iRetCode = AddToBagPage(stWillAddItemData, iNum, iBagType, pAddedNum);
    CHECK_ERR(m_ownerId, iRetCode, "AddToBagTab, iBagType:%d", iBagType);

    return 0;
}

/**
 * @brief 根据物品ID添加物品（货币类透传至IncMoney）
 */
int NFBagPageOpMgrInterface::AddToBag(int iItemId, int iNum, int* pAddedNum)
{
    // 货币类物品直接调用增加货币接口
    if (NFItemUtil::IsValidMoney(iItemId))
    {
        return IncMoney(iItemId, iNum, pAddedNum);
    }

    // 普通物品：构造数据并调用标准添加流程
    WillAddItemData stWillAddItemData;
    stWillAddItemData.id = iItemId;
    return AddToBag(stWillAddItemData, iNum, pAddedNum);
}

/**
 * @brief 添加物品到指定页签
 * - 货币类直通 IncMoney
 * - 嵌套创建禁止操作
 * - 调用 AddItemFix 修正绑定/品质
 * - 背包满时可通过 AddItemWhenBagFull 转流（邮件等）
 */
int NFBagPageOpMgrInterface::AddToBagPage(WillAddItemData& stWillAddItemData, int iNum, int iBagType, int* pAddedNum)
{
    int iRetCode = 0;

    // 货币类物品透传
    if (NFItemUtil::IsValidMoney(stWillAddItemData.id))
    {
        return IncMoney(stWillAddItemData.id, iNum, pAddedNum);
    }

    // 嵌套创建防护：禁止在已存在的操作管理器内再次创建
    if (m_bNestCreate)
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    // 修正物品属性（绑定、品质等）
    iRetCode = AddItemFix(stWillAddItemData, iBagType);
    CHECK_ERR(0, iRetCode, "AddWareFix, iBagType:%d", iBagType);

    // 获取或创建指定页签的操作器
    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL(m_ownerId, pBagPageOp);

    // 调用页签操作器执行添加
    int iAddNum = 0;
    iRetCode = pBagPageOp->AddItem(stWillAddItemData, iNum, iAddNum);
    CHECK_ERR(m_ownerId, iRetCode, "pOpContainer->AddWares");

    // 如未全部添加且未禁止背包满转流，则尝试溢出处理（如发邮件）
    if (iAddNum < iNum && !m_bForbidAddWheFull)
    {
        int iLeftNum = iNum - iAddNum;
        int iLeftAddNum = 0;
        iRetCode = AddItemWhenBagFull(stWillAddItemData, iLeftNum, iLeftAddNum);
        CHECK_ERR(m_ownerId, iRetCode, "AddItemWhenBagFull, item:{} iLeftNum:{}", stWillAddItemData.id, iLeftNum);
        iAddNum += iLeftAddNum;
    }
    // 计算最终添加结果：未添加完且要求全部添加时返回页签满错误码
    iRetCode = CalcAddResult(*pBagPageOp, iNum, iAddNum, pAddedNum);
    CHECK_ERR(m_ownerId, iRetCode, "CalcAddResult");
    return 0;
}

/**
 * @brief 批量添加物品（自动选择页签）
 * @param astWillAddItemData 待添加物品数据列表
 * @param aiWantAddNum 期望添加数量列表
 * @param paiAddedNum 输出实际添加数量列表（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBag(std::vector<WillAddItemData>& astWillAddItemData, const std::vector<int>& aiWantAddNum, std::vector<int>* paiAddedNum)
{
    int iRetCode = 0;
    CHECK_EXPR(astWillAddItemData.size() == aiWantAddNum.size(), -1, "astWillAddItemData.size() != aiWantAddNum.size()", astWillAddItemData.size(), aiWantAddNum.size());

    if (paiAddedNum)
    {
        paiAddedNum->resize(astWillAddItemData.size());
    }

    for (int i = 0; i < (int)astWillAddItemData.size(); i++)
    {
        WillAddItemData& stWillAddItemData = astWillAddItemData[i];
        int iWantAddNum = aiWantAddNum[i];
        if (paiAddedNum)
        {
            int iAddedNum = 0;
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, &iAddedNum);
            (*paiAddedNum)[i] = iAddedNum;
        }
        else
        {
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, nullptr);
        }
        CHECK_ERR(m_ownerId, iRetCode, "AddToBag");
    }

    return 0;
}

/**
 * @brief 批量添加物品（带数量的物品数据）
 * @param astWillAddItemData 待添加物品数据列表（含数量）
 * @param paiAddedNum 输出实际添加数量列表（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBag(std::vector<WillAddItemDataWithNum>& astWillAddItemData, std::vector<int>* paiAddedNum)
{
    int iRetCode = 0;

    if (paiAddedNum)
    {
        paiAddedNum->resize(astWillAddItemData.size());
    }

    for (int i = 0; i < (int)astWillAddItemData.size(); i++)
    {
        WillAddItemData& stWillAddItemData = astWillAddItemData[i].m_stAddItem;
        int iWantAddNum =  astWillAddItemData[i].m_iNum;
        if (paiAddedNum)
        {
            int iAddedNum = 0;
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, &iAddedNum);
            (*paiAddedNum)[i] = iAddedNum;
        }
        else
        {
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, nullptr);
        }
        CHECK_ERR(m_ownerId, iRetCode, "AddToBag");
    }

    return 0;
}

/**
 * @brief 添加物品（使用物品对象）
 * @param stItem 物品对象
 * @param iNum 要添加的数量
 * @param pAddedNum 输出实际添加数量（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBag(NFGridItem& stItem, int iNum, int* pAddedNum)
{
    int iRetCode = 0;

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(stItem, m_enPackageOpReason, iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "CServicePackage::CalcAddBagTab");

    iRetCode = AddToBagPage(stItem, iNum, iBagType, pAddedNum);
    CHECK_ERR(m_ownerId, iRetCode, "AddToBagTab, iBagType:%d", iBagType);

    return 0;
}

/**
 * @brief 批量添加物品到指定页签
 * @param astWillAddItemData 待添加物品数据列表
 * @param aiWantAddNum 期望添加数量列表
 * @param iBagType 目标页签类型
 * @param paiAddedNum 输出实际添加数量列表（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBagPage(std::vector<WillAddItemData>& astWillAddItemData, const std::vector<int>& aiWantAddNum, int iBagType, std::vector<int>* paiAddedNum)
{
    int iRetCode = 0;
    CHECK_EXPR(astWillAddItemData.size() == aiWantAddNum.size(), -1, "astWillAddItemData.size() != aiWantAddNum.size()", astWillAddItemData.size(), aiWantAddNum.size());

    if (paiAddedNum)
    {
        paiAddedNum->resize(astWillAddItemData.size());
    }

    for (int i = 0; i < (int)astWillAddItemData.size(); i++)
    {
        WillAddItemData& stWillAddItemData = astWillAddItemData[i];
        int iWantAddNum = aiWantAddNum[i];
        if (paiAddedNum)
        {
            int iAddedNum = 0;
            iRetCode = AddToBagPage(stWillAddItemData, iWantAddNum, iBagType, &iAddedNum);
            (*paiAddedNum)[i] = iAddedNum;
        }
        else
        {
            iRetCode = AddToBagPage(stWillAddItemData, iWantAddNum, iBagType, nullptr);
        }
        CHECK_ERR(m_ownerId, iRetCode, "AddToBag");
    }

    return 0;
}

/**
 * @brief 添加物品到指定页签（物品对象版本）
 * @param stItem 物品对象
 * @param iNum 要添加的数量
 * @param iBagType 目标页签类型
 * @param pAddedNum 输出实际添加数量（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBagPage(NFGridItem& stItem, int iNum, int iBagType, int* pAddedNum)
{
    int iRetCode = 0;

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    iRetCode = AddItemFix(stItem, iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "AddWareFix, item:{} iBagType:{}", stItem.ShortDebugString(), iBagType);

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL(m_ownerId, pBagPageOp);

    int iAddNum = 0;
    iRetCode = pBagPageOp->AddItem(&stItem, iNum, iAddNum);
    CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->AddItem, item:{} iBagType:{}", stItem.ShortDebugString(), iBagType);
    if (iAddNum < iNum && !m_bForbidAddWheFull)
    {
        int iLeftNum = iNum - iAddNum;
        int iLeftAddNum = 0;
        iRetCode = AddItemWhenBagFull(&stItem, iLeftNum, iLeftAddNum);
        CHECK_ERR(m_ownerId, iRetCode, "AddItemWhenBagFull, item:{} iLeftNum:{}", stItem.ShortDebugString(), iLeftNum);
        iAddNum += iLeftAddNum;
    }
    iRetCode = CalcAddResult(*pBagPageOp, iNum, iAddNum, pAddedNum);
    CHECK_ERR(m_ownerId, iRetCode, "CalcAddResult, item:{} iBagType:{} iNum:{} iAddNum:{}", stItem.ShortDebugString(), iBagType, iNum, iAddNum);

    return 0;
}

/**
 * @brief 添加物品到指定页签（尽量/必须模式）
 * @param stWillAddItemData 待添加物品数据
 * @param iNum 要添加的数量
 * @param iBagType 目标页签类型
 * @param bAsPossible true=尽量添加，false=必须全部添加
 * @param pAddedNum 输出实际添加数量（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBagPage(WillAddItemData& stWillAddItemData, int iNum, int iBagType, bool bAsPossible, int* pAddedNum)
{
    int iRetCode = 0;

    if (NFItemUtil::IsValidMoney(stWillAddItemData.id))
    {
        return IncMoney(stWillAddItemData.id, iNum, pAddedNum);
    }

    int iAddedNum = iNum;
    if (bAsPossible)
    {
        iRetCode = AddToBagPage(stWillAddItemData, iNum, iBagType, &iAddedNum);
    }
    else
    {
        iRetCode = AddToBagPage(stWillAddItemData, iNum, iBagType, nullptr);
    }
    CHECK_ERR(m_ownerId, iRetCode, "AddToBagTab");

    if (pAddedNum != nullptr)
    {
        *pAddedNum = iAddedNum;
    }
    return 0;
}

/**
 * @brief 添加物品（尽量/必须模式，自动选择页签）
 * @param stWillAddItemData 待添加物品数据
 * @param iNum 要添加的数量
 * @param bAsPossible true=尽量添加，false=必须全部添加
 * @param pAddedNum 输出实际添加数量（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBag(WillAddItemData& stWillAddItemData, int iNum, bool bAsPossible, int* pAddedNum)
{
    int iRetCode = 0;
    if (NFItemUtil::IsValidMoney(stWillAddItemData.id))
    {
        return IncMoney(stWillAddItemData.id, iNum, pAddedNum);
    }

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(stWillAddItemData, m_enPackageOpReason, iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "CServicePackage::CalcAddBagTab");

    iRetCode = AddToBagPage(stWillAddItemData, iNum, iBagType, pAddedNum);
    CHECK_ERR(m_ownerId, iRetCode, "AddToBagPage, iBagType:%d", iBagType);
    return 0;
}

/**
 * @brief 根据物品ID添加（尽量/必须模式）
 * @param iItemId 物品ID
 * @param iNum 要添加的数量
 * @param bAsPossible true=尽量添加，false=必须全部添加
 * @param pAddedNum 输出实际添加数量（可选）
 * @return 0成功，非0失败
 */
int NFBagPageOpMgrInterface::AddToBag(int iItemId, int iNum, bool bAsPossible, int* pAddedNum)
{
    if (NFItemUtil::IsValidMoney(iItemId))
    {
        return IncMoney(iItemId, iNum, pAddedNum);
    }
    WillAddItemData stWillAddItemData;
    stWillAddItemData.id = iItemId;
    return AddToBag(stWillAddItemData, iNum, bAsPossible, pAddedNum);
}

/**
 * @brief 添加物品到指定页签（bool 模式版本）
 * @param bAsPossible true=尽量添加，false=必须全部添加
 */
int NFBagPageOpMgrInterface::AddToBagPage(NFGridItem& stItem, int iNum, int iBagType, bool bAsPossible, int* pAddedNum)
{
    int iRetCode = 0;

    if (bAsPossible)
    {
        int iAddNum = 0;
        iRetCode = AddToBagPage(stItem, iNum, iBagType, &iAddNum);
        if (pAddedNum)
        {
            *pAddedNum = iAddNum;
        }
    }
    else
    {
        iRetCode = AddToBagPage(stItem, iNum, iBagType, nullptr);
    }
    CHECK_ERR(m_ownerId, iRetCode, "AddToBagTab");

    return 0;
}

/**
 * @brief 自动选择页签添加物品（bool 模式版本）
 * @param bAsPossible true=尽量添加，false=必须全部添加
 */
int NFBagPageOpMgrInterface::AddToBag(NFGridItem& stItem, int iNum, bool bAsPossible, int* pAddedNum)
{
    int iRetCode = 0;

    if (bAsPossible)
    {
        int iAddNum = 0;
        iRetCode = AddToBag(stItem, iNum, &iAddNum);
        if (pAddedNum)
        {
            *pAddedNum = iAddNum;
        }
    }
    else
    {
        iRetCode = AddToBag(stItem, iNum, nullptr);
    }
    CHECK_ERR(m_ownerId, iRetCode, "AddToBag");

    return 0;
}

/**
 * @brief 批量添加物品（向量版本）
 * 依次添加多个物品，支持尽量添加模式
 * @param astWillAddItemData 待添加物品数据数组
 * @param aiWantAddNum 对应数量数组
 * @param paiAddedNum 非空时返回每个物品实际添加数量
 */
int NFBagPageOpMgrInterface::AddToBag(std::vector<WillAddItemData>& astWillAddItemData, const std::vector<int>& aiWantAddNum, bool bAsPossible, std::vector<int>* paiAddedNum)
{
    int iRetCode = 0;

    // 校验数组大小一致
    if (astWillAddItemData.size() != aiWantAddNum.size())
    {
        CHECK_ERR(m_ownerId, -1, "astWillAddWareData.size():{} aiWantAddNum.size():{}", static_cast<uint32_t>(astWillAddItemData.size()), static_cast<uint32_t>(aiWantAddNum.size()));
    }
    if (paiAddedNum != nullptr)
    {
        paiAddedNum->resize(astWillAddItemData.size());
    }

    // 依次添加每个物品
    for (std::size_t i = 0; i < astWillAddItemData.size(); ++i)
    {
        WillAddItemData& stWillAddItemData = astWillAddItemData[i];
        int iWantAddNum = aiWantAddNum[i];

        if (paiAddedNum != nullptr)
        {
            int iAddedNum = 0;
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, &iAddedNum);
            (*paiAddedNum)[i] = iAddedNum;
        }
        else
        {
            iRetCode = AddToBag(stWillAddItemData, iWantAddNum, nullptr);
        }
        CHECK_ERR(m_ownerId, iRetCode, "AddToBag");
    }

    return 0;
}

/**
 * @brief 批量添加物品（Item 结构体版本）
 * 根据 Item 数组添加物品，支持返回未添加完的剩余物品
 * @param vecWares 待添加物品数组
 * @param pVecLeftWares 非空时返回未添加完的剩余物品
 */
int NFBagPageOpMgrInterface::AddItems(const std::vector<Item>& vecWares, bool bAsPossible, std::vector<Item>* pVecLeftWares)
{
    int iRetCode = 0;

    for (int i = 0; i < (int)vecWares.size(); i++)
    {
        WillAddItemData stWillAddItemData;
        stWillAddItemData.id = vecWares[i].id;
        stWillAddItemData.quality = vecWares[i].quality;

        int pAddedNum = 0;
        iRetCode = AddToBag(stWillAddItemData, vecWares[i].value, bAsPossible, &pAddedNum);
        CHECK_ERR(m_ownerId, iRetCode, "AddToBag");

        if ((int)vecWares[i].value != pAddedNum)
        {
            if (pVecLeftWares)
            {
                Item newItem = vecWares[i];
                newItem.value -= pAddedNum;
                pVecLeftWares->push_back(newItem);
            }
        }
    }
    return 0;
}

int NFBagPageOpMgrInterface::AddItemFix(WillAddItemData& stWillAddItemData, int iBagType) const
{
    auto pDesc = ItemDesc::Instance()->GetDesc(stWillAddItemData.id);
    CHECK_NULL(m_ownerId, pDesc);

    stWillAddItemData.role_bind = NFItemUtil::IsBind(stWillAddItemData.role_bind, *pDesc, m_enBindStatForAdd);
    switch (pDesc->item_type)
    {
        case proto_ff::EN_ITEM_TYPE_BUFF:
        case proto_ff::EN_ITEM_TYPE_PROP:
        case proto_ff::EN_ITEM_TYPE_TITLE:
        case proto_ff::EN_ITEM_TYPE_MATERIAL:
        case proto_ff::EN_ITEM_TYPE_BOX:
        case proto_ff::EN_ITEM_TYPE_GEMSTONE:
        case proto_ff::EN_ITEM_TYPE_PARTNER_EQUIP_STONE:
        {
            stWillAddItemData.quality = 0;
            break;
        }
        case proto_ff::EN_ITEM_TYPE_ID:
        {
            stWillAddItemData.quality = pDesc->item_rank;
        }
        default:
        {
            break;
        }
    }
    return 0;
}

/**
 * @brief 修正物品属性（NFGridItem 版本）
 * 根据物品配置与添加模式设置绑定状态与品质
 * - 特定类型物品（道具/材料等）品质归零
 * - ID类物品品质取配置中的 item_rank
 */
int NFBagPageOpMgrInterface::AddItemFix(NFGridItem& stItem, int iBagType) const
{
    auto pDesc = ItemDesc::Instance()->GetDesc(stItem.GetItemID());
    CHECK_NULL(m_ownerId, pDesc);

    // 计算并设置绑定状态
    bool bBind = NFItemUtil::IsBind(stItem.IsBind(), *pDesc, m_enBindStatForAdd);
    stItem.SetBind(bBind);

    // 设置物品类型并修正品质
    stItem.m_iItemType = pDesc->item_type;
    switch (pDesc->item_type)
    {
        case proto_ff::EN_ITEM_TYPE_BUFF:
        case proto_ff::EN_ITEM_TYPE_PROP:
        case proto_ff::EN_ITEM_TYPE_TITLE:
        case proto_ff::EN_ITEM_TYPE_MATERIAL:
        case proto_ff::EN_ITEM_TYPE_BOX:
        case proto_ff::EN_ITEM_TYPE_GEMSTONE:
        case proto_ff::EN_ITEM_TYPE_PARTNER_EQUIP_STONE:
        {
            stItem.SetQuality(0);
            break;
        }
        case proto_ff::EN_ITEM_TYPE_ID:
        {
            stItem.SetQuality(pDesc->item_rank);
        }
        default:
        {
            break;
        }
    }
    return 0;
}

/**
 * @brief 根据物品获取目标页签操作器（NFGridItem 版本）
 * 根据物品与操作原因计算应添加到的页签类型，返回对应操作器
 */
NFBagPageOp* NFBagPageOpMgrInterface::GetBagPageOpForAddToBagPage(const NFGridItem* pItem)
{
    int iRetCode = 0;
    CHECK_NULL_RE_NULL(m_ownerId, pItem, "");

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(*pItem, GetPackageOpReason(), iBagType);
    CHECK_ERR_RE_NULL(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_RE_NULL(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:%d", iBagType);

    return pBagPageOp;
}

/**
 * @brief 根据待添加物品数据获取目标页签操作器
 * 根据物品数据与操作原因计算应添加到的页签类型，返回对应操作器
 */
NFBagPageOp* NFBagPageOpMgrInterface::GetBagPageOpForAddToBagPage(const WillAddItemData& stWillAddItemData)
{
    int iRetCode = 0;

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(stWillAddItemData, GetPackageOpReason(), iBagType);
    CHECK_ERR_RE_NULL(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_RE_NULL(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:%d", iBagType);

    return pBagPageOp;
}

/**
 * @brief 为指定物品ID添加合适的页签操作器
 * 根据物品ID计算应添加到的页签类型，并添加对应页签操作器
 */
int NFBagPageOpMgrInterface::AddSuitableBagPage(int iItemID)
{
    int iRetCode = 0;
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return 0;
    }

    std::vector<int> vecTabIndexs;
    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(iItemID, GetPackageOpReason(), iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    vecTabIndexs.push_back(iBagType);
    iRetCode = AddBagPageOp(vecTabIndexs);
    CHECK_ERR(m_ownerId, iRetCode, "AddBagPageOp");
    return 0;
}

/**
 * @brief 批量添加页签操作器
 * 根据页签类型数组，获取或创建对应的页签操作器
 */
int NFBagPageOpMgrInterface::AddBagPageOp(const std::vector<int>& vecTabIndexs)
{
    for (int i = 0; i < (int)vecTabIndexs.size(); ++i)
    {
        int iBagType = vecTabIndexs[i];
        NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
        CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:%d", iBagType);
    }

    return 0;
}

NFBagPageOp* NFBagPageOpMgrInterface::GetBagPageOpByBagType(int iBagType)
{
    int iRetCode = 0;
    NFBagPageInterfacePackage* pCWareContainerInterfacePackage = nullptr;
    iRetCode = AllocInterfacePackage(iBagType, pCWareContainerInterfacePackage);
    // 外部调用参数错误
    CHECK_ERR_RE_NULL(m_ownerId, iRetCode, "AllocInterfacePackage, iBagType:%d", iBagType);
    CHECK_NULL_RE_NULL(m_ownerId, pCWareContainerInterfacePackage, "iBagType:%d", iBagType);
    return GetBagPageOp(pCWareContainerInterfacePackage);
}

NFBagPageOp* NFBagPageOpMgrInterface::GetBagPageOp(NFBagPageInterface* pBagPageInterface)
{
    CHECK_NULL_RE_NULL(m_ownerId, pBagPageInterface, "");

    NFBagPageOp* pBagPageOp = FindBagPageOp(pBagPageInterface);
    if (pBagPageOp == NULL)
    {
        pBagPageOp = CreateBagPageOp(pBagPageInterface);
        CHECK_NULL_RE_NULL(m_ownerId, pBagPageOp, "CreateBagPageOp");
    }

    return pBagPageOp;
}

int NFBagPageOpMgrInterface::AllocInterfacePackage(int iBagType, NFBagPageInterfacePackage*& pInterface)
{
    CHECK_EXPR(NFItemUtil::IsValidBagType(iBagType), -1, "iBagType:{}", iBagType);

    NFBagPage* pBagPage = GetBagPage(iBagType);
    CHECK_NULL(m_ownerId, pBagPage);

    pInterface = nullptr;
    pInterface = GetInterfacePackage(pBagPage);
    if (pInterface)
    {
        return 0;
    }

    pInterface = CreateInterfacePackage(pBagPage);
    CHECK_NULL(0, pInterface);

    return 0;
}

NFBagPageInterfacePackage* NFBagPageOpMgrInterface::GetInterfacePackage(NFBagPage* pBagPage)
{
    for (int i = 0; i < (int)m_vecCacheInterfacePackage.size(); i++)
    {
        NFBagPageInterfacePackage* pInterface = m_vecCacheInterfacePackage[i];
        if (pInterface && pInterface->GetBagPage() == pBagPage)
        {
            return pInterface;
        }
    }
    return nullptr;
}

NFBagPageInterfacePackage* NFBagPageOpMgrInterface::CreateInterfacePackage(NFBagPage* pBagPage)
{
    NFBagPageInterfacePackage* pInterface = new NFBagPageInterfacePackage(pBagPage);
    m_vecCacheInterfacePackage.push_back(pInterface);
    return pInterface;
}

/**
 * @brief 计算添加结果并处理页签满逻辑
 * 若未全部添加且要求必须全部添加，则返回页签满错误码
 * @param pAddedNum 非空时尽量添加，空时必须全部添加
 */
int NFBagPageOpMgrInterface::CalcAddResult(NFBagPageOp& stBagPageOp, int iWantAddNum, int iRealAddNum, int* pAddedNum)
{
    int iRetCode = 0;
    if (iRealAddNum < iWantAddNum)
    {
        int iTabFullErrCode = 0;
        iRetCode = stBagPageOp.GetErrCodeWhenFull(iTabFullErrCode);
        CHECK_ERR(0, iRetCode, "stBagPageOp.GetErrCodeWhenFull");

        // 记录所有类型页签满的错误码，外部可以获取发错误码
        m_setTabFullErrCodes.insert(iTabFullErrCode);

        if (pAddedNum == nullptr) // 必须全部添加完,返回页签满错误码
        {
            CHECK_ERR(0, iTabFullErrCode, "iWantAddNum:{} iRealAddNum:{}", iWantAddNum, iRealAddNum);
        }
    }

    if (pAddedNum)
    {
        *pAddedNum = iRealAddNum;
    }
    return 0;
}

/**
 * @brief 查找已存在的页签操作器
 * 根据页签接口指针在已创建的操作器中查找
 */
NFBagPageOp* NFBagPageOpMgrInterface::FindBagPageOp(NFBagPageInterface* pBagPageInterface)
{
    for (int i = 0; i < (int)m_allBagPageOps.size(); i++)
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[i];
        if (pBagPageOp && pBagPageOp->GetBagPageInterface() == pBagPageInterface)
        {
            return pBagPageOp;
        }
    }
    return nullptr;
}

/**
 * @brief 创建新的页签操作器
 * 分配新的 NFBagPageOp 对象，初始化并加入管理列表
 */
NFBagPageOp* NFBagPageOpMgrInterface::CreateBagPageOp(NFBagPageInterface* pBagPageInterface)
{
    NFBagPageOp* pInterface = new NFBagPageOp();
    pInterface->Init(this, pBagPageInterface);
    m_allBagPageOps.push_back(pInterface);
    m_vecPackage.push_back(pInterface);
    return pInterface;
}

/**
 * @brief 从所有页签中删除指定物品
 * 遍历所有页签操作器，依次尝试删除直到达到目标数量
 * @param piDelNum 非空时尽量删除，空时必须全部删除
 */
int NFBagPageOpMgrInterface::DelAllItems(int iItemID, int iNum, int* piDelNum)
{
    int iRetCode = 0;
    LOG_DEBUG(m_ownerId, "DelAllItems, iItemID:{} iNum:{}", iItemID, iNum);

    // 货币类物品透传至货币系统
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return DecMoney(iItemID, iNum, piDelNum);
    }

    // 嵌套创建防护
    if (m_bNestCreate)
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    // 依次从所有页签中删除
    int iLeftNum = iNum;
    int iDelNum = 0;
    for (int i = 0; i < (int)m_allBagPageOps.size() && iLeftNum > 0; i++)
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[i];
        if (pBagPageOp && NFItemUtil::IsValidOpBagType(pBagPageOp->GetBagType()))
        {
            int iBagPageDelItemNum = 0;
            iRetCode = pBagPageOp->DelItem(iItemID, iLeftNum, &iBagPageDelItemNum);
            CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItems, iItemID:{} iLeftNum:{} iBagPageDelItemNum:{}", iItemID, iLeftNum, iBagPageDelItemNum);

            iLeftNum -= iBagPageDelItemNum;
            iDelNum += iBagPageDelItemNum;
        }
    }

    //尽量删除，设置实际删除个数
    if (piDelNum)
    {
        *piDelNum = iDelNum;
    }
    //全部删除
    else
    {
        if (iDelNum != iNum)
        {
            CHECK_ERR(m_ownerId, ERR_CODE_ITEM_NOT_ENOUGH, "iItemID:{} iNum:{} iDelNum:{}", iItemID, iNum, iDelNum);
        }
    }
    return 0;
}

int NFBagPageOpMgrInterface::DelItems(int iItemID, int iNum, int* piDelNum)
{
    int iRetCode = 0;
    LOG_DEBUG(m_ownerId, "DelItems, iItemID:{} iNum:{}", iItemID, iNum);

    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return DecMoney(iItemID, iNum, piDelNum);
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(iItemID, GetPackageOpReason(), iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:{}", iBagType);

    int iBagPageDelItemNum = 0;
    iRetCode = pBagPageOp->DelItem(iItemID, iNum, &iBagPageDelItemNum);
    CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItems, iItemID:{} iNum:{} iBagPageDelItemNum:{}", iItemID, iNum, iBagPageDelItemNum);

    //尽量删除，设置实际删除个数
    if (piDelNum)
    {
        *piDelNum = iBagPageDelItemNum;
    }
    //全部删除
    else
    {
        if (iBagPageDelItemNum != iNum)
        {
            CHECK_ERR(m_ownerId, ERR_CODE_ITEM_NOT_ENOUGH, "iItemID:{} iNum:{} iDelNum:{}", iItemID, iNum, iBagPageDelItemNum);
        }
    }
    return 0;
}

int NFBagPageOpMgrInterface::DelItemsByUUid(int iItemID, uint64_t ullItemUUid)
{
    int iRetCode = 0;
    LOG_DEBUG(m_ownerId, "DelItems, iItemID:{} ullItemUUid:{}", iItemID, ullItemUUid);
    if (iItemID <= 0 || ullItemUUid <= 0)
    {
        return ERR_CODE_INVALID_REQ_PARAM;
    }

    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return ERR_CODE_ITEM_NOT_EXIST;
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(iItemID, GetPackageOpReason(), iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:{}", iBagType);

    iRetCode = pBagPageOp->DelItemByItemIdAndUUid(iItemID, ullItemUUid);
    CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItemsByItemIdAndUUid, iItemID:{} ullItemUUid:{}", iItemID, ullItemUUid);

    return 0;
}

int NFBagPageOpMgrInterface::DelItems(const std::vector<NFBagPageOp*>& vecBagPageOp, int iItemID, int iWantDelNum, int& iRealDelNum)
{
    int iRetCode = 0;
    LOG_DEBUG(m_ownerId, "DelItems, iItemID:{} iWantDelNum:{}", iItemID, iWantDelNum);
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return DecMoney(iItemID, iWantDelNum, &iRealDelNum);
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    int iLeftNum = iWantDelNum;
    for (int i = 0; i < (int)vecBagPageOp.size() && iLeftNum > 0; i++)
    {
        NFBagPageOp* pBagPageOp = vecBagPageOp[i];
        if (pBagPageOp)
        {
            int iBagPageDelItemNum = 0;
            iRetCode = pBagPageOp->DelItem(iItemID, iLeftNum, &iBagPageDelItemNum);
            CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItems, iItemID:{} iLeftNum:{} iBagPageDelItemNum:{}", iItemID, iLeftNum, iBagPageDelItemNum);

            iLeftNum -= iBagPageDelItemNum;
            iRealDelNum += iBagPageDelItemNum;
        }
    }

    return 0;
}

void NFBagPageOpMgrInterface::DelSameItemsOutInit(int* piRealDelNum, bool* pbHadDelBind)
{
    if (piRealDelNum)
    {
        *piRealDelNum = 0;
    }

    if (pbHadDelBind)
    {
        *pbHadDelBind = false;
    }
}

int NFBagPageOpMgrInterface::DelSameItemsNeedProc(const std::vector<ItemOpData>& vecItemOpData, int iWantDelNum, int* piRealDelNum, bool& bNeedProc, uint64_t& ullOwnerRoleID, int& iItemID)
{
    bNeedProc = false;
    ullOwnerRoleID = 0;
    iItemID = 0;

    if (iWantDelNum < 1)
    {
        LOG_DEBUG(m_ownerId, "iWantDelNum:{}", iWantDelNum);
        return 0;
    }

    if (vecItemOpData.empty())
    {
        if (piRealDelNum == nullptr)
        {
            CHECK_ERR(m_ownerId, ERR_CODE_ITEM_NOT_ENOUGH, "vecItemOpData.empty()");
        }

        LOG_DEBUG(m_ownerId, "vecItemOpData.empty()");
        return 0;
    }

    auto pItem = vecItemOpData[0].pItem;
    iItemID = pItem->GetItemID();
    ullOwnerRoleID = m_ownerId;
    LOG_DEBUG(m_ownerId, "DelSameItems, iItemID:{} iWantDelNum:{}", iItemID, iWantDelNum);

    int iTotalNum = 0;
    for (int i = 0; i < (int)vecItemOpData.size(); i++)
    {
        pItem = vecItemOpData[i].pItem;
        if (pItem->GetItemID() != iItemID)
        {
            CHECK_ERR(m_ownerId, -1, "pItem->GetItemID():{} != iItemID:{} i:{}", pItem->GetItemID(), iItemID, i);
        }

        iTotalNum += pItem->GetNumber();
    }
    LOG_DEBUG(m_ownerId, "iTotalNum:{}", iTotalNum);

    if (piRealDelNum == nullptr && iTotalNum < iWantDelNum)
    {
        CHECK_ERR(m_ownerId, ERR_CODE_ITEM_NOT_ENOUGH, "iWantDelNum:{} iTotalNum:{}", iWantDelNum, iTotalNum);
    }

    bNeedProc = true;
    return 0;
}

int NFBagPageOpMgrInterface::DelSameItems(std::vector<ItemOpData>& vecItemOpData, NFItemOpDataCompareFun pSortFunc, int iWantDelNum, int* piRealDelNum, bool* pbHadDelBind)
{
    int iRetCode = 0;
    DelSameItemsOutInit(piRealDelNum, pbHadDelBind);

    bool bNeedProc = false;
    uint64_t ullOwnerRoleID = 0;
    int iItemID = 0;
    iRetCode = DelSameItemsNeedProc(vecItemOpData, iWantDelNum, piRealDelNum, bNeedProc, ullOwnerRoleID, iItemID);
    CHECK_ERR(m_ownerId, iRetCode, "DelSameItemsNeedProc");

    if (!bNeedProc)
    {
        return 0;
    }

    if (pSortFunc)
    {
        std::stable_sort(vecItemOpData.begin(), vecItemOpData.end(), pSortFunc);
    }

    int iCanDelNum = iWantDelNum;
    int iRealDelNum = 0;
    iRetCode = DelSameItemsDel(vecItemOpData, iCanDelNum, iRealDelNum, pbHadDelBind);
    CHECK_ERR(m_ownerId, iRetCode, "DelSameItemsDel");

    if (piRealDelNum)
    {
        *piRealDelNum = iRealDelNum;
    }

    return 0;
}

int NFBagPageOpMgrInterface::DelSameItemsDel(const std::vector<ItemOpData>& vecItemOpData, int iCanDelNum, int& iRealDealNum, bool* pbHadDelBind)
{
    int iRetCode = 0;
    iRealDealNum = 0;

    int iLeftNum = iCanDelNum;
    for (int i = 0; i < (int)vecItemOpData.size() && iLeftNum > 0; i++)
    {
        auto& stItemOpData = vecItemOpData[i];
        auto pBagPageOp = stItemOpData.pBagPageOp;
        /*if (pBagPageOp->GetBagPageOpMgr() != this)
        {
            CHECK_ERR(m_ownerId, -1, "pCWareContainerOp pCWareContainerOp->GetContainers() != this");
        }*/

        int iThisRealDelNum = 0;
        iRetCode = pBagPageOp->DelItemByGridWithNum(stItemOpData.iGridIndex, iLeftNum, &iThisRealDelNum);
        CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItemByGridWithNum");

        LOG_DEBUG(m_ownerId, "DelSameItemsDel, iItemID:{} iGridIndex:{} iCanDelNum:{} iThisRealDelNum:{}", stItemOpData.pItem->GetItemID(), stItemOpData.iGridIndex, iCanDelNum, iThisRealDelNum);

        if (iThisRealDelNum <= 0)
        {
            continue;
        }

        iLeftNum -= iThisRealDelNum;

        if (pbHadDelBind != nullptr && stItemOpData.pItem->IsBind())
        {
            *pbHadDelBind = true;
        }
    }

    iRealDealNum = iCanDelNum - iLeftNum;
    LOG_DEBUG(m_ownerId, "iCanDelNum:%d - iLeftNum:%d = iRealDealNum:%d", iCanDelNum, iLeftNum, iRealDealNum);
    return 0;
}

int NFBagPageOpMgrInterface::DelItemByGridIndex(int iBagType, int iGridIndex, int iNum)
{
    int iRetCode = 0;
    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:{} iGridIndex:{}", iBagType, iGridIndex);

    iRetCode = pBagPageOp->DelItemByGridWithNum(iGridIndex, iNum);
    CHECK_ERR(0, iRetCode, "pBagPageOp->DelItemByGridWithNum, iBagType:{} iGridIndex:{}", iBagType, iGridIndex);

    return 0;
}

int NFBagPageOpMgrInterface::DelAllItems(int iItemId)
{
    int iRetCode = 0;
    if (NFItemUtil::IsValidMoney(iItemId))
    {
        int pllDelNum = 0;
        return DecMoney(iItemId, GetMoneyNumber(iItemId), &pllDelNum);
    }

    AddAllBagPage();

    for (int iContainerIndex = 0; iContainerIndex < (int)m_allBagPageOps.size(); ++iContainerIndex) // 遍历所有容器
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[iContainerIndex];
        if (pBagPageOp && NFItemUtil::IsValidOpBagType(pBagPageOp->GetBagType()))
        {
            iRetCode = pBagPageOp->DelAllByItemID(iItemId);
            CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelAllBagItems, iItemID:{}", iItemId);
        }
    }

    return 0;
}

int NFBagPageOpMgrInterface::DelItems(const WillDelItemData& stWillDelWareData, int* piDelNum)
{
    int iRetCode = 0;

    if (NFItemUtil::IsValidMoney(stWillDelWareData.m_iItemID))
    {
        return DecMoney(stWillDelWareData.m_iItemID, stWillDelWareData.m_iWantDelNum, piDelNum);
    }

    std::vector<int> aiBagType;
    iRetCode = NFItemUtil::GetBagTabsForDel(stWillDelWareData, aiBagType);
    CHECK_ERR(m_ownerId, iRetCode, "FPackageUtil::GetBagTabsForDel");

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    int iDelNum = 0;
    int iLeftNum = stWillDelWareData.m_iWantDelNum;
    for (int i = 0; i < (int)aiBagType.size() && iLeftNum > 0; i++)
    {
        int iBagType = aiBagType[i];
        NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
        CHECK_NULL_WF(m_ownerId, pBagPageOp, "pBagPageOp->DelItemsByUUidFromSuitableBagType, iBagType:{} iItemID:{}", iBagType, stWillDelWareData.m_iItemID);

        int iRealDelNum = 0;
        iRetCode = pBagPageOp->DelItem(stWillDelWareData.m_iItemID, iLeftNum, &iRealDelNum);
        CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->DelItemsByUUidFromSuitableBagType, iBagType:{} iItemID:{} iLeftNum:{} iRealDelNum:{}", iBagType, stWillDelWareData.m_iItemID, iLeftNum, iRealDelNum);

        iDelNum += iRealDelNum;
        iLeftNum -= iRealDelNum;
    }

    if (piDelNum)
    {
        *piDelNum = iDelNum;
    }
    //全部删除
    else
    {
        if (iDelNum != stWillDelWareData.m_iWantDelNum)
        {
            CHECK_ERR(m_ownerId, ERR_CODE_ITEM_NOT_ENOUGH, "iItemID:{} iWantDelNum:{} iDelNum:{}", stWillDelWareData.m_iItemID, stWillDelWareData.m_iWantDelNum, iDelNum);
        }
    }
    return 0;
}

int NFBagPageOpMgrInterface::DelBindItem(int iItemID, int iWantDelNum, int* piRealDelNum)
{
    int iRetCode = 0;
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        return DecMoney(iItemID, iWantDelNum, piRealDelNum);
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    // 获取可以删除的物品
    std::vector<ItemOpData> vecItemOpData;

    GetOpItemParam stParam;
    stParam.iBindType = EN_BT_FORCE_BIND;

    int iTotalNum = 0;
    iRetCode = ForEachBagPageOp([&](NFBagPageOp& stOpContainer, bool& bStop) -> int
    {
        std::vector<ItemOpData> vecTempItemOpData;
        iRetCode = stOpContainer.GetOpWareData(iItemID, &stParam, vecTempItemOpData);
        CHECK_ERR(m_ownerId, iRetCode, "stOpContainer.ForEachWareBase");

        for (std::size_t i = 0; i < vecTempItemOpData.size(); ++i)
        {
            const NFGridItem* pItem = vecTempItemOpData[i].pItem;
            CHECK_NULL(m_ownerId, pItem);
            iTotalNum += pItem->GetNumber();
        }
        // 找够就停
        bStop = (iTotalNum >= iWantDelNum);

        vecItemOpData.assign(vecTempItemOpData.begin(), vecTempItemOpData.end());
        return 0;
    });
    CHECK_ERR(m_ownerId, iRetCode, "ForEachBagPageOp");

    // 想要全部删除，但是总个数不够
    if (piRealDelNum == nullptr && iTotalNum < iWantDelNum)
    {
        CHECK_ERR(m_ownerId, -1, "iWantDelNum:%d but only find iTotalNum:%d", iWantDelNum, iTotalNum);
    }

    // 开始删除
    int iRealDealNum = 0;
    iRetCode = DelSameItemsDel(vecItemOpData, iWantDelNum, iRealDealNum, nullptr);
    CHECK_ERR(m_ownerId, iRetCode, "DelSameWaresDel");

    if (piRealDelNum != nullptr)
    {
        *piRealDelNum = iRealDealNum;
    }
    // piRealDelNum == null
    else if (iRealDealNum < iWantDelNum) // 想要全部删除，但是总个数不够
    {
        // 前面检测过了，这里不应该不够
        CHECK_ERR(m_ownerId, -1, "iWantDelNum:%d find iTotalNum:%d but iRealDealNum:%d", iWantDelNum, iTotalNum, iRealDealNum);
    }

    return 0;
}

int NFBagPageOpMgrInterface::HaveEnoughAllItem(int iItemID, int iNum, bool& bEnough)
{
    int iRetCode = 0;

    if (NFItemUtil::IsValidMoney(iItemID))
    {
        int64_t ullNum = (int)GetMoneyNumber(iItemID);
        bEnough = ullNum >= (int64_t)iNum;
        return 0;
    }

    int iLeftCheckNum = iNum;
    for (int i = 0; i < (int)m_allBagPageOps.size() && iLeftCheckNum > 0; i++)
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[i];
        if (pBagPageOp && NFItemUtil::IsValidOpBagType(pBagPageOp->GetBagType()))
        {
            int iContainerWareNum = 0;
            iRetCode = pBagPageOp->GetItemNum(iItemID, iLeftCheckNum, iContainerWareNum);
            CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->GetItemNum, iItemID:%d", iItemID);
            iLeftCheckNum -= iContainerWareNum;
        }
    }

    bEnough = iLeftCheckNum <= 0; // 有足够的个数
    return 0;
}

int NFBagPageOpMgrInterface::HaveEnoughItem(int iItemID, int iNum, bool& bEnough)
{
    int iRetCode = 0;

    if (NFItemUtil::IsValidMoney(iItemID))
    {
        int64_t ullNum = (int)GetMoneyNumber(iItemID);
        bEnough = ullNum >= (int64_t)iNum;
        return 0;
    }

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(iItemID, GetPackageOpReason(), iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:%d", iBagType);

    int iLeftCheckNum = iNum;

    int iContainerWareNum = 0;
    iRetCode = pBagPageOp->GetItemNum(iItemID, iLeftCheckNum, iContainerWareNum);
    CHECK_ERR(m_ownerId, iRetCode, "pBagPageOp->GetItemNum, iItemID:%d", iItemID);
    iLeftCheckNum -= iContainerWareNum;

    bEnough = iLeftCheckNum <= 0; // 有足够的个数
    return 0;
}

int NFBagPageOpMgrInterface::GetItemNum(int iItemID, int& iItemNum)
{
    int iRetCode = 0;
    iItemNum = 0;
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        iItemNum = (int)GetMoneyNumber(iItemID);
        return 0;
    }

    int iBagType = 0;
    iRetCode = NFItemUtil::CalcAddBagType(iItemID, GetPackageOpReason(), iBagType);
    CHECK_ERR(m_ownerId, iRetCode, "NFPackageUtil::CalcAddBagType");

    NFBagPageOp* pBagPageOp = GetBagPageOpByBagType(iBagType);
    CHECK_NULL_WF(m_ownerId, pBagPageOp, "GetBagPageOpByBagType, iBagType:{}", iBagType);

    int iBagItemNum = 0;
    iRetCode = pBagPageOp->GetItemNum(iItemID, iBagItemNum);
    CHECK_ERR(0, iRetCode, "pBagPageOp->GetItemNum， iItemID:{} iBagItemNum:{}", iItemID, iBagItemNum);
    iItemNum += iBagItemNum;

    return 0;
}

int NFBagPageOpMgrInterface::GetAllItemNum(int iItemID, int& iItemNum)
{
    int iRetCode = 0;
    iItemNum = 0;
    if (NFItemUtil::IsValidMoney(iItemID))
    {
        iItemNum = (int)GetMoneyNumber(iItemID);
        return 0;
    }

    for (int i = 0; i < (int)m_allBagPageOps.size(); i++)
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[i];
        if (pBagPageOp && NFItemUtil::IsValidOpBagType(pBagPageOp->GetBagType()))
        {
            int iBagItemNum = 0;
            iRetCode = pBagPageOp->GetItemNum(iItemID, iBagItemNum);
            CHECK_ERR(0, iRetCode, "pBagPageOp->GetItemNum， iBagItemNum:%d", iBagItemNum);
            iItemNum += iBagItemNum;
        }
    }

    return 0;
}

int NFBagPageOpMgrInterface::SwapGrid(int iSrcBagType, int iSrcGridIndex, int iTargetBagType, int iTargetGridIndex)
{
    NFBagPageOp* pSrcBagPageOp = nullptr;
    NFBagPageOp* pTargetBagPageOp = nullptr;

    if (iSrcBagType == iTargetBagType && iSrcGridIndex == iTargetGridIndex)
    {
        return 0;
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    pSrcBagPageOp = GetBagPageOpByBagType(iSrcBagType);
    CHECK_NULL_WF(m_ownerId, pSrcBagPageOp, "iSrcBagType:%d", iSrcBagType);
    pTargetBagPageOp = GetBagPageOpByBagType(iTargetBagType);
    CHECK_NULL_WF(m_ownerId, pTargetBagPageOp, "iTargetBagType:%d", iTargetBagType);

    NFGridItem* pSrcItem = pSrcBagPageOp->GetMutableItem(iSrcGridIndex);
    CHECK_NULL_WF(m_ownerId, pSrcItem, "iSrcGridIndex:%d", iSrcGridIndex);
    NFGridItem* pTargetItem = pTargetBagPageOp->GetMutableItem(iTargetGridIndex);
    CHECK_NULL_WF(m_ownerId, pTargetItem, "iTargetGridIndex:%d", iTargetGridIndex);

    NFGridItem stTmpWare;
    stTmpWare = *pSrcItem;
    *pSrcItem = *pTargetItem;
    *pTargetItem = stTmpWare;

    return 0;
}

int NFBagPageOpMgrInterface::MoveWare(int iBagTypeSrc, int iGridIndexSrc, int iBagTypeTarget)
{
    NFBagPageOp* pSrcContainer = nullptr;
    NFBagPageOp* pTargetContainer = nullptr;

    if (iBagTypeSrc == iBagTypeTarget)
    {
        return 0;
    }

    if (m_bNestCreate) // 是嵌套创建的本对象，不允许操作
    {
        CHECK_ERR(m_ownerId, -1, "nest create, can`t be op");
    }

    pSrcContainer = GetBagPageOpByBagType(iBagTypeSrc);
    CHECK_NULL_WF(m_ownerId, pSrcContainer, "iBagTypeSrc:%d", iBagTypeSrc);
    pTargetContainer = GetBagPageOpByBagType(iBagTypeTarget);
    CHECK_NULL_WF(m_ownerId, pTargetContainer, "iBagTypeTarget:%d", iBagTypeTarget);

    return pSrcContainer->MoveOneGridItemToOtherBagPage(iGridIndexSrc, -1, *pTargetContainer, nullptr);
}

int NFBagPageOpMgrInterface::FindMutableItem(uint64_t ullUUID, NFGridItem*& pItemOut, NFBagPageOp*& pBagPageOp)
{
    pItemOut = nullptr;
    pBagPageOp = nullptr;

    int iRetCode = 0;
    LOG_DEBUG(m_ownerId, "ullUUID:%lu", ullUUID);

    iRetCode = ForEachBagPageOp([&](NFBagPageOp& stBagPageOp, bool& bStop) -> int
    {
        iRetCode = stBagPageOp.ForEachItem([&](int iGridIndex, const NFGridItem& stItem, bool& bStop) -> int
        {
            if (stItem.GetUUID() == ullUUID)
            {
                LOG_DEBUG(m_ownerId, "find iGridIndex:{} ItemID:{}", iGridIndex, stItem.GetItemID());
                pItemOut = stBagPageOp.GetMutableItem(iGridIndex);
                pBagPageOp = &stBagPageOp;
                bStop = true;
            }
            return 0;
        });
        CHECK_ERR(m_ownerId, iRetCode, "stBagPageOp.ForEachItem");

        bStop = (pItemOut != nullptr);
        return 0;
    });
    CHECK_ERR(m_ownerId, iRetCode, "ForEachBagPageOp");

    return 0;
}

int NFBagPageOpMgrInterface::ForEachBagPageOp(const std::function<int(NFBagPageOp&, bool&)>& func)
{
    int iRetCode = 0;

    for (int iContainerIndex = 0; iContainerIndex < (int)m_allBagPageOps.size(); ++iContainerIndex) // 遍历所有容器
    {
        NFBagPageOp* pBagPageOp = m_allBagPageOps[iContainerIndex];
        if (pBagPageOp && NFItemUtil::IsValidOpBagType(pBagPageOp->GetBagType()))
        {
            bool bStop = false;
            iRetCode = func(*pBagPageOp, bStop);
            CHECK_ERR(0, iRetCode, "func proc");
            if (bStop)
            {
                break;
            }
        }
    }

    return 0;
}



